/*
 * Created by Jaren at 2021/11/28 10:22
 */
import 'dart:typed_data';

import 'package:binary/src/boxed_int.dart';
import 'package:inmotion_protocol/base/vehicle_data.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/mode.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/base/vehicle_real_time_info.dart';
import 'package:inmotion_protocol/lorin/bean/euc/euc_real_time_data.dart';
import 'package:inmotion_protocol/lorin/bean/euc/v13/v13_real_time_data.dart';
import 'package:inmotion_protocol/lorin/constant.dart';
import 'package:inmotion_protocol/util/byte_util.dart';
import 'package:inmotion_protocol/util/version.dart';

class AllV11RealTimeData extends AllRealTimeData<V11RealTimeInfo, V11RealTimeState, V11RealTimeError> {
  AllV11RealTimeData(V11RealTimeInfo realTimeInfo, V11RealTimeState realTimeState, V11RealTimeError realTimeError) : super(realTimeInfo, realTimeState, realTimeError);
}

class V11VehicleSynthesizeRealTimeInfo extends VehicleSynthesizeRealTimeInfo<CommonVehicleRealTimeInfo, V11RealTimeState, V11RealTimeError> {
  V11VehicleSynthesizeRealTimeInfo(CommonVehicleRealTimeInfo commonVehicleRealTimeInfo, V11RealTimeState realTimeState, V11RealTimeError realTimeError) : super(commonVehicleRealTimeInfo, realTimeState, realTimeError);
}

/// 实时信息
class V11RealTimeInfo extends EucRealTimeInfo {
  V11RealTimeInfo(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    if (model.isV11Y()) {
      compact = _DefaultV11YRealTimeInfo();
    } else {
      String hmicVersion = version.getAppVersionByDevice(Constant.deviceEUCV11HMIC);
      if (VersionUtils.higherOrEquals(hmicVersion, VersionConstant.v11Hmic1228)) {
        compact = _V11RealTimeInfoV137();
      } else if (VersionUtils.higherOrEquals(hmicVersion, VersionConstant.v11Hmic129)) {
        compact = _V11RealTimeInfoV131();
      } else {
        compact = _DefaultV11RealTimeInfo();
      }
    }
  }

  @override
  String toString() {
    String compactType = compact.runtimeType.toString();
    return 'V11RealTimeInfo{compact:$compactType, voltage: $voltage, current: $current, speed: $speed, mileage: $mileage, batteryLevel: $batteryLevel, '
        'remainderRange: $remainderRange, torque: $torque, batteryOutputPower: $batteryOutputPower, motorOutputPower: $motorOutputPower, '
        'outputRate: $outputRate, batteryMode: $batteryMode, batteryLevelForRide: $batteryLevelForRide, estimatedTotalMileage: $estimatedTotalMileage, '
        'mosTemp: $mosTemp, motorTemp: $motorTemp, batteryTemp: $batteryTemp, boardTemp: $boardTemp, lampTemp: $lampTemp, pitchAngle: $pitchAngle, '
        'pitchAimAngle: $pitchAimAngle, rollAngle: $rollAngle, speedingBrakingAngle: $speedingBrakingAngle, dynamicCurrentLimit: $dynamicCurrentLimit, '
        'dynamicSpeedLimit: $dynamicSpeedLimit, brightness: $brightness, lightBrightness: $lightBrightness, cpuTemp: $cpuTemp, imuTemp: $imuTemp}';
  }
}

class _DefaultV11RealTimeInfo extends Compact<V11RealTimeInfo> {
  @override
  void fromBytes(V11RealTimeInfo output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + output.length()) {
      return;
    }

    output.voltage = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.current = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speed = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.torque = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.batteryOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.motorOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.mileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.remainderRange = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.batteryLevel = ByteUtil.toUint16((bytes[offset] & 0x7F) * 100); // 保证协议库对外电量单位为0.01%
    output.batteryMode = ByteUtil.toInt8((bytes[offset] & 0x80) >> 7);
    offset++;
    output.mosTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.motorTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.batteryTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.boardTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.lampTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.pitchAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAimAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.rollAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.dynamicSpeedLimit = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.dynamicCurrentLimit = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.brightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.cpuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.imuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
  }

  @override
  int length() {
    return 36;
  }
}

class _V11RealTimeInfoV131 extends _DefaultV11RealTimeInfo {
  @override
  int length() {
    return 38;
  }
}

class _V11RealTimeInfoV137 extends Compact<V11RealTimeInfo> {
  @override
  void fromBytes(V11RealTimeInfo output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + output.length()) {
      return;
    }
    output.voltage = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.current = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speed = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.torque = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.outputRate = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.batteryOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.motorOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    // 保留2bytes
    offset += 2;
    output.pitchAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.rollAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAimAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speedingBrakingAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.mileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    // 保留2bytes
    offset += 2;
    output.batteryLevel = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.batteryLevelForRide = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.estimatedTotalMileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    output.remainderRange = Uint16(((output.batteryLevelForRide.value / 10000) * output.estimatedTotalMileage.value).toInt());
    offset += 2;
    output.dynamicSpeedLimit = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.dynamicCurrentLimit = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;

    // 保留4bytes
    offset += 2;
    offset += 2;

    output.mosTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.motorTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.batteryTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.boardTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.cpuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.imuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.lampTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.brightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    // 保留5bytes
  }

  @override
  int length() {
    return 56;
  }
}

class _DefaultV11YRealTimeInfo extends Compact<V11RealTimeInfo> {
  @override
  void fromBytes(V11RealTimeInfo output, Uint8ClampedList bytes, int offset) {
    output.voltage = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.current = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    // 跳过chargeVoltage(2byte) + chargeCurrent(2byte)
    offset += 2;
    offset += 2;

    output.speed = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    // 跳过acceleration(2byte)
    offset += 2;
    output.torque = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.outputRate = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.batteryOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.motorOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.rollAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAimAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speedingBrakingAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.mileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;

    // 保留4byte
    offset += 4;

    output.batteryLevel = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.batteryLevelForRide = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;

    output.estimatedTotalMileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    output.remainderRange = Uint16(((output.batteryLevelForRide.value / 10000) * output.estimatedTotalMileage.value).toInt());
    offset += 2;

    // 使用翘板速度作为动态限速值
    output.dynamicSpeedLimit = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    // 跳过rtOverOutputTiltBackThr(2byte) + rtOverOutputWarningThr(2byte) + rtOverBusCurrentTiltBackThr(2byte) + rtOverBusCurrentWarningThr(2byte) + rtPhaseCurrentLimit(2byte)
    offset += 2;
    offset += 2;
    offset += 2;
    offset += 2;
    offset += 2;
    offset += 2;

    // 保留4byte
    offset += 4;

    output.mosTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.motorTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.batteryTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.boardTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.cpuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.imuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;

    // 跳过batteryMaxCellTemp(1byte)
    offset++;
    // 跳过batteryMaxBmsTemp(1byte)
    offset++;
    output.lampTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset++;
    output.brightness = ByteUtil.toUint8(bytes[offset]);
    offset++;
    output.lightBrightness = ByteUtil.toUint8(bytes[offset]);
    offset++;

    // 保留5byte
  }

  @override
  int length() {
    return 74;
  }
}

/// 实时状态
class V11RealTimeState extends EucRealTimeState {
  Uint4 decorativeLightState = Uint4.zero;
  Uint4 fanState = Uint4.zero;

  V11RealTimeState(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    if (model.isV11Y()) {
      compact = _DefaultV11YRealTimeState();
    } else {
      String hmicVersion = version.getAppVersionByDevice(Constant.deviceEUCV11HMIC);
      if (VersionUtils.higherOrEquals(hmicVersion, VersionConstant.v11Hmic1228)) {
        compact = _V11RealTimeStateV137();
      } else if (VersionUtils.higherOrEquals(hmicVersion, VersionConstant.v11Hmic129)) {
        compact = _V11RealTimeStateV131();
      } else {
        compact = _DefaultV11RealTimeState();
      }
    }
  }

  @override
  String toString() {
    return 'V11RealTimeState{pcMode: $pcMode, lightState: $headlightState, dfuState: $dfuState,mcMode: $mcMode, motorState: $motorState, chargeState: $chargeState, '
        'liftedState: $liftedState, tailLightState: $tailLightState, backupBatteryState: $backupBatteryState, brakeState: $brakeState, slowDownState: $slowDownState,'
        'decorativeLightState: $decorativeLightState, fanState: $fanState}';
  }
}

class _DefaultV11RealTimeState extends Compact<V11RealTimeState> {
  @override
  void fromBytes(V11RealTimeState output, Uint8ClampedList bytes, int offset) {
    // 3bit
    output.pcModeValue = ByteUtil.toUint32(ByteUtil.bitValue(bytes[offset], 0, 3).value);
    if (output.pcModeValue.value == 0) {
      output.pcMode = Mode.idle;
    } else if (output.pcModeValue.value == 1) {
      output.pcMode = Mode.working;
    } else if (output.pcModeValue.value == 2) {
      output.pcMode = Mode.sleep;
    } else if (output.pcModeValue.value == 3) {
      output.pcMode = Mode.locked;
    }
    output.lockState = output.pcMode == Mode.locked ? Uint4(1) : Uint4.zero;
    // 3bit
    output.mcMode = ByteUtil.bitValue(bytes[offset], 3, 3);
    // 1bit
    output.motorState = ByteUtil.bitValue(bytes[offset], 6, 1);
    // 1bit
    output.chargeState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    // 1bit
    output.headlightState = ByteUtil.bitValue(bytes[offset], 0, 1);
    // 1bit
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 1, 1);
    // 1bit
    output.liftedState = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 2bit
    output.tailLightState = ByteUtil.bitValue(bytes[offset], 3, 2);
    // 1bit
    output.fanState = ByteUtil.bitValue(bytes[offset], 5, 1);
    // 剩余2bit+2byte保留
  }

  @override
  int length() {
    return 4;
  }
}

class _V11RealTimeStateV131 extends _DefaultV11RealTimeState {}

class _V11RealTimeStateV137 extends Compact<V11RealTimeState> {
  @override
  void fromBytes(V11RealTimeState output, Uint8ClampedList bytes, int offset) {
    // 3bit
    output.pcModeValue = ByteUtil.toUint32(ByteUtil.bitValue(bytes[offset], 0, 3).value);
    if (output.pcModeValue.value == 0) {
      output.pcMode = Mode.idle;
    } else if (output.pcModeValue.value == 1) {
      output.pcMode = Mode.working;
    } else if (output.pcModeValue.value == 2) {
      output.pcMode = Mode.sleep;
    } else if (output.pcModeValue.value == 3) {
      output.pcMode = Mode.locked;
    }
    output.lockState = output.pcMode == Mode.locked ? Uint4(1) : Uint4.zero;
    // 3bit
    output.mcMode = ByteUtil.bitValue(bytes[offset], 3, 3);
    // 1bit
    output.motorState = ByteUtil.bitValue(bytes[offset], 6, 1);
    // 1bit
    output.chargeState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    // 1bit
    output.backupBatteryState = ByteUtil.bitValue(bytes[offset], 0, 1);
    // 1bit
    output.headlightState = ByteUtil.bitValue(bytes[offset], 1, 1);
    // 1bit
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 1bit
    output.liftedState = ByteUtil.bitValue(bytes[offset], 3, 1);
    // 2bit
    output.tailLightState = ByteUtil.bitValue(bytes[offset], 4, 3);
    // 1bit
    output.fanState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    // 1bit
    output.brakeState = ByteUtil.bitValue(bytes[offset], 0, 1);
    // 1bit
    output.slowDownState = ByteUtil.bitValue(bytes[offset], 1, 1);
    // 1bit
    output.dfuState = ByteUtil.bitValue(bytes[offset], 2, 1);
  }

  @override
  int length() {
    return 4;
  }
}

class _DefaultV11YRealTimeState extends Compact<V11RealTimeState> {
  @override
  void fromBytes(V11RealTimeState output, Uint8ClampedList bytes, int offset) {
    // 3bit
    output.pcModeValue = ByteUtil.toUint32(ByteUtil.bitValue(bytes[offset], 0, 3).value);
    if (output.pcModeValue.value == 0) {
      output.pcMode = Mode.idle;
    } else if (output.pcModeValue.value == 1) {
      output.pcMode = Mode.working;
    } else if (output.pcModeValue.value == 2) {
      output.pcMode = Mode.sleep;
    } else if (output.pcModeValue.value == 3) {
      output.pcMode = Mode.locked;
    }
    output.lockState = output.pcMode == Mode.locked ? Uint4(1) : Uint4.zero;
    // 3bit
    output.mcMode = ByteUtil.bitValue(bytes[offset], 3, 3);
    // 1bit
    output.motorState = ByteUtil.bitValue(bytes[offset], 6, 1);
    // 1bit
    output.chargeState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    // 1bit
    output.backupBatteryState = ByteUtil.bitValue(bytes[offset], 0, 1);
    // 跳过chargePortDetectState(3bit) + chargePortOnState(1bit) + dcPortDetectState(3bit)
    offset++;

    // 跳过dcOutputEnableState(1bit)
    // 1bit
    output.headlightState = ByteUtil.bitValue(bytes[offset], 1, 1);
    // 1bit
    output.decorativeLightState = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 1bit
    output.liftedState = ByteUtil.bitValue(bytes[offset], 3, 1);
    // 3bit
    output.tailLightState = ByteUtil.bitValue(bytes[offset], 4, 3);
    // 1bit
    output.fanState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.brakeState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.slowDownState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.dfuState = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 剩余保留
  }

  @override
  int length() {
    return 4;
  }
}

/// 实时故障和警告
class V11RealTimeError extends V13RealTimeError {
  V11RealTimeError(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    if (model.isV11Y()) {
      compact = _DefaultV11YRealTimeError();
    } else {
      compact = _DefaultV11RealTimeError();
    }
  }
}

class _DefaultV11RealTimeError extends Compact<V11RealTimeError> {
  @override
  void fromBytes(V11RealTimeError output, Uint8ClampedList bytes, int offset) {
    output.originalValue = ByteUtil.bytes2Int32Le(bytes, offset);

    output.iPhaseSensorState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.iBusSensorState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.motorHallState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.batteryState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.imuSensorState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.controllerCom1State = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.controllerCom2State = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.bleCom1State = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.bleCom2State = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.mosTempSensorState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.motorTempSensorState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.batteryTempSensorState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.boardTempSensorState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.fanState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.rtcState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.externalRomState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.vBusSensorState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.vBatterySensorState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.canNotPowerOffState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.canNotChargeState = ByteUtil.bitValue(bytes[offset], 3, 1);
    // 剩余4bit保留
    // 剩余1byte保留
    offset++;

    offset++;

    // 警告
    output.underVoltageState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.overVoltageState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.overBusCurrentState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.lowBatteryState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.overMosTempState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.overMotorTempState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.overBatteryTempState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.overBoardTempState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.overSpeedState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.outputSaturationState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.motorSpinState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.motorBlockState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.postureState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.riskBehaviourState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;

    output.motorNoLoadState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.noSelfTestState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.compatibilityState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.powerKeyLongPressState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.forceDfuState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.deviceLockState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.cpuOverTempState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.imuOverTempState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;

    output.hwCompatibilityState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.fanLowSpeedState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.someBatteriesNotWorkState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.batteryNotCaliState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.chargeDangerWarningLevel = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.chargeDangerWarningHandledState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.lockedBySafetyIssueState = ByteUtil.bitValue(bytes[offset], 7, 1);
  }

  @override
  int length() {
    return 8;
  }
}

class _DefaultV11YRealTimeError extends DefaultV13RealTimeErrorDelegate<V11RealTimeError> {}
